import { Injectable } from '@angular/core';

class AbstractSdkEntity {
    url : string;

    transporter : (any) => void;

    responseHandler : () => void;

    requestFilter : () => void;

    defaultSuccess : () => void;

    defaultFail : () => void;

    setUrl(url : string) {
        this.url = url;
    }

    setTransporter(transporter : (any) => void) {
        this.transporter = transporter;
    }

    getTransporter() : (any) => void {
       return this.transporter;
    }

    setResponseHandler(responseHandler : () => void) {
        this.responseHandler = responseHandler;
    }

    setRequestFilter(requestFilter : () => void) {
        this.requestFilter = requestFilter;
    }

    setDefaultSuccess(defaultSuccess : () => void) {
        this.defaultSuccess = defaultSuccess;
    }

    setDefaultFail(defaultFail : () => void) {
        this.defaultFail = defaultFail;
    }

    setCallback(defaultSuccess : () => void, defaultFail : () => void) {
        this.defaultSuccess = defaultSuccess;
        this.defaultFail = defaultFail;
    }
}

class AbstractInterfaceDelegate extends AbstractSdkEntity {
    constructor(sdk : AbstractSdkEntity) {
        super();

        console.log("AbstractInterfaceDelegate.constructor, sdk=" + sdk);
    }

    invokeMethod(requestObject) {
        let transporter = this.getTransporter();
        console.log("AbstractInterfaceDelegate.invokeMethod, requestObject=" + requestObject);
        return new Promise((resolve, reject) => {
             transporter(requestObject);
        });
    }
}

<#list interfaces?sort_by("name") as interface>
class ${interface.name}Delegate extends AbstractInterfaceDelegate {
    <#list interface.methods?sort_by("name") as method>
    ${method.name}(argumentObject) {
        return super.invokeMethod({
            interfaceType:"${interface.name}",
            methodName:"${method.name}",
            argumentObject:argumentObject
        });
    }
    </#list>
}
</#list>

@Injectable()
export class DubboApiTypeScriptSdk extends AbstractSdkEntity{
    <#list interfaces?sort_by("name") as interface>
    ${interface.name}() {
        return new ${interface.name}Delegate(this);
    }
    </#list>
}